package io.bdmc.common.utils;

import com.alibaba.fastjson2.JSONObject;
import io.bdmc.common.exception.CMSException;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.util.*;

@Slf4j
public class DTSConfigUtil {

    /**
     * 将配置写到文件
     *
     * @param bs       字节
     * @param dtsIp    ip
     * @param fileName 默认文件名，不带路径，空字符串默认ip为文件名
     */
    public static void writeToConfig(byte[] bs, String dtsIp, String fileName) {
        try {
            File f = getIniFileByIp(dtsIp, fileName);
            if (f.exists()) {
                FileWriter fileWriter = new FileWriter(f);
                fileWriter.write("");
                fileWriter.flush();
                fileWriter.close();
            }
            OutputStream oStream = new FileOutputStream(f);
            oStream.write(bs);
            oStream.close();
            log.info("INI写入完成，本地文件名:" + f.getCanonicalPath());
        } catch (IOException exception) {
            log.error(exception.toString());
        }
    }

    /**
     * 从dts的配置文件读取ini文件
     *
     * @param dtsIp dts的ip
     * @return 读取到的map
     */
    public static Map<String, Object> getGlobalConfig(String dtsIp) {
        Map<String, Object> map = new HashMap<>(8);
        BufferedReader br = null;
        try {
            File f = getIniFileByIp(dtsIp, "");
            if (!f.exists()) {
                throw new CMSException("文件不存在");
            }
            // FileInputStream inputStream = new FileInputStream(f);
            br = new BufferedReader(new FileReader(f));
            String line;

            String sep = "     ";
            while ((line = br.readLine()) != null) {
                if (StringUtils.isBlank(line))
                    break;
                if (line.contains("Global"))
                    continue;
                String key = line.split(sep)[0];
                String val = line.split(sep)[1];
                map.put(key, val);
            }
        } catch (IOException e) {
            log.error("ini文件读取异常：" + dtsIp);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return map;
    }

    /**
     * 将map读内容写入到ini
     *
     * @param map   需要写入的参数map
     * @param dtsIp dts的ip地址
     */
    public static String setGlobalConfig(Map<String, Object> map, String dtsIp) {
        BufferedReader br = null;
        try {
            File f = getIniFileByIp(dtsIp, "");
            br = new BufferedReader(new FileReader(f));
            String line;
            String sep = "     ";
            StringBuilder buf = new StringBuilder();
            Set<String> keySet = map.keySet();
            boolean inGlobal = false;
            while ((line = br.readLine()) != null) {
                // 读到空白行就跳出
                if (StringUtils.isBlank(line)) {
                    inGlobal = false;
                    buf.append("\n");
                    continue;
                }
                if (line.contains("Global")) {
                    inGlobal = true;
                }

                // 包含key 则覆盖该行
                String key;
                if (inGlobal && keySet.contains(key = line.split(sep)[0])) {
                    String newLine = key + sep + map.get(key);
                    buf.append(newLine).append("\n");
                } else {
                    buf.append(line).append("\n");
                }
            }
            return buf.toString();
        } catch (IOException ex) {
            log.error("组包出错：" + dtsIp);
            return "";
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据ip和通道号获取指定通道的配置信息
     *
     * @param dtsIp   dts设备的ip
     * @param channel 通道
     * @return 配置的map
     */
    public static Map<String, Object> getChannelConfig(String dtsIp, int channel) {
        Map<String, Object> map = new HashMap<>(8);
        Map<String, String> basicMap = new HashMap<>(8);
        List<String> insplaceList = new ArrayList<>();
        List<String> revisecoefList = new ArrayList<>();
        List<String> connectList = new ArrayList<>();
        map.put("basic", basicMap);
        map.put("insplace", insplaceList);
        map.put("revisecoef", revisecoefList);
        map.put("connect", connectList);
        BufferedReader br = null;
        try {
            File f = getIniFileByIp(dtsIp, "");
            if (!f.exists()) {
                throw new CMSException("文件不存在");
            }
            br = new BufferedReader(new FileReader(f));
            String line, sec = "", ch = "Ch" + channel, sep = "     ";
            while ((line = br.readLine()) != null) {
                if (line.contains(ch + "_basic")) {
                    sec = "basic";
                    continue;
                }
                if (line.contains(ch + "_insplace")) {
                    sec = "insplace";
                    continue;
                }
                if (line.contains(ch + "_revisecoef")) {
                    sec = "revisecoef";
                    continue;
                }
                if (line.contains(ch + "_connect")) {
                    sec = "connect";
                    continue;
                }
                if (StringUtils.isBlank(line) && sec.length() > 0) {
                    // 读到ch的空行,如果是connect 则不读了
                    if (sec.equals("connect"))
                        break;
                    continue;
                }
                switch (sec) {
                    case "basic":
                        final String[] conf = line.split(sep);
                        basicMap.put(conf[0], conf[1]);
                        break;
                    case "insplace":
                        insplaceList.add(line);
                        break;
                    case "revisecoef":
                        revisecoefList.add(line.replace(sep, ","));
                        break;
                    case "connect":
                        connectList.add(line);
                        break;
                    default:
                        break;
                }

            }
        } catch (IOException e) {
            log.error(e.toString());
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return map;
    }

    public static String setChannelConfig(JSONObject json, String dtsIp, Integer channel) {
        BufferedReader br = null;
        try {
            String ch = "Ch" + channel;
            File f = getIniFileByIp(dtsIp, "");
            br = new BufferedReader(new FileReader(f));
            boolean inChSec = false;
            ;
            String sep = "     ", sec = "", line;
            StringBuilder buf = new StringBuilder();
            JSONObject basic = json.getJSONObject("basic");

            // boolean inChBasic = false,insplace = false,revisecoef = false,connect =
            // false;

            while ((line = br.readLine()) != null) {
                if (line.contains(ch + "_basic")) {
                    buf.append(line).append("\n");
                    sec = "basic";
                    inChSec = true;
                }
                if (line.contains(ch + "_insplace")) {
                    buf.append(line).append("\n");
                    sec = "insplace";
                }
                if (line.contains(ch + "_revisecoef")) {
                    buf.append(line).append("\n");
                    sec = "revisecoef";
                }
                if (line.contains(ch + "_connect")) {
                    buf.append(line).append("\n");
                    sec = "connect";
                }

                if (sec.length() > 0) {
                    if (StringUtils.isBlank(line)) {
                        // 读connect下面的空行 则不写了
                        buf.append("\n");
                        continue;
                    }
                }

                switch (sec) {
                    case "basic":
                        basic.forEach((key, value) -> {
                            String newLine = key + sep + value;
                            buf.append(newLine).append("\n");
                        });
                        sec = "";
                        break;
                    case "insplace":
                        String[] ins = json.getObject("insplace", String[].class);
                        for (String in : ins) {
                            buf.append(in).append("\n");
                        }
                        sec = "";
                        break;
                    case "revisecoef":
                        String[] rev = json.getObject("revisecoef", String[].class);
                        for (String in : rev) {
                            buf.append(in).append("\n");
                        }
                        sec = "";
                        break;
                    case "connect":
                        String[] con = json.getObject("connect", String[].class);
                        for (String in : con) {
                            buf.append(in).append("\n");
                        }
                        sec = "";
                        inChSec = false;
                        break;
                    default:
                        if (!inChSec) {
                            buf.append(line).append("\n");
                        } else if (StringUtils.isBlank(line)) {
                            buf.append("\n");
                        }
                        break;
                }

            }
            return buf.toString();
        } catch (IOException ex) {
            log.error("组包出错：" + dtsIp);
            return "";
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 根据ip和文件名获取文件路径
     * 
     * @param dtsIp    ip地址
     * @param fileName 文件名 ，空文件名则以ip作为文件名
     * @return 指定config.txt文件
     * @throws IOException io异常
     */
    private static File getIniFileByIp(String dtsIp, String fileName) throws IOException {
        String localFileName;
        if (StringUtils.isBlank(fileName)) {
            localFileName = dtsIp.replace(".", "-") + ".txt";
        } else {
            localFileName = dtsIp.replace(".", "-") + "-" + fileName + ".txt";
        }

        File path = new File(Constant.EXPORTPATH + Constant.DTSConfigPath);
        if (!path.exists()) {
            if (!path.mkdir()) {
                throw new IOException("目录创建失败:" + path);
            }
        }
        return new File(path.getAbsolutePath(), localFileName);
    }
}
